#include "Verlet.h"

Verlet::Verlet(MODEL*m)
{
    esferas=&m->SPHList;
    pModel=m;
    dt = m->Precision;
}
VerletParalelo::VerletParalelo(MODEL*m)
{
    esferas=&m->SPHList;
    pModel=m;
    dt = m->Precision;
}
void Verlet::integra(SPHERE*s)
{
		REAL A[3], Am[3];

		A[0] = s->F[0] / s->Mass;
		A[1] = s->F[1] / s->Mass;
		A[2] = s->F[2] / s->Mass;

		s->F[0] = s->F[1] = s->F[2] = 0.0;

		Am[0] = 0.5 * (s->A0[0] + A[0]);
		Am[1] = 0.5 * (s->A0[1] + A[1]);
		Am[2] = 0.5 * (s->A0[2] + A[2]);

		s->R[0] += (s->V[0] + 0.5 * Am[0] * dt) * dt;
		s->R[1] += (s->V[1] + 0.5 * Am[1] * dt) * dt;
		s->R[2] += (s->V[2] + 0.5 * Am[2] * dt) * dt;

		s->V[0] += Am[0] * dt;
		s->V[1] += Am[1] * dt;
		s->V[2] += Am[2] * dt;

		s->A0[0] = A[0];
		s->A0[1] = A[1];
		s->A0[2] = A[2];

		while (s->R[2] > CONST_PI) s->R[2] -= CONST_2_PI;
		while (s->R[2] < -CONST_PI) s->R[2] += CONST_2_PI;
}
void Verlet::calcular()
{
    #pragma omp single
    {
        for (SPHERE* s = pModel->SPHList.Begin; s != NULL; s = s->Next) integra(s);
        pModel->Time += dt;
    }
}
void VerletParalelo::calcular()
{
    #pragma omp for schedule (dynamic,1)
    for (int i = 0; i < pModel->numProceEsf; i++)
    {
        SPHERE* testeFim;
        if (i!=pModel->numProceEsf-1) testeFim = pModel->threads[i+1];
        else testeFim=NULL;

        for (SPHERE* s = pModel->threads[i]; s != testeFim; s = s->Next) integra(s);
    }
    #pragma omp barrier
    #pragma omp single
    {
        pModel->Time += dt;
    }
}
